import { DrawerForm, ProTable, ProFormInstance, ActionType, ProColumns, ProFormText, ProFormSelect } from '@ant-design/pro-components';
import { Row, Col, message, Button, Popconfirm } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import React, { useEffect, useRef, useState } from 'react';
import { LpProTableBaseColumnType, LpProTableProps, RecordAttr } from './type';

function LpProTable<T extends LpProTableBaseColumnType<T>>(props: LpProTableProps<T>) {
    const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
    const [drawerVisit, setDrawerVisit] = useState(false);
    const [modalFormMode, setModalFormMode] = useState({ title: '新增', mode: 'add' });
    const [drawerFormValues, setDrawerFormValues] = useState<T>({} as any);

    const actionRef = useRef<ActionType>();
    const drawerFormRef = useRef<ProFormInstance>();

    useEffect(() => {
        // console.log('init');
    }, []);

    useEffect(() => {
        if (drawerVisit) {
            if (modalFormMode.mode !== 'add') {
                // 显示时，编辑场景，表单初始化
                drawerFormRef?.current?.setFieldsValue({ ...drawerFormValues });
            } else {
                drawerFormRef?.current?.resetFields();
            }
        } else {
            drawerFormRef?.current?.resetFields();
        }
    }, [drawerVisit]);

    const handleExpand = (_expanded: boolean, record: T) => {
        const key = record.id;
        const index = expandedRowKeys.indexOf(key);

        if (index > -1) {
            // 已经展开，需要收起
            setExpandedRowKeys(expandedRowKeys.filter(k => k !== key));
        } else {
            // 未展开，需要展开
            setExpandedRowKeys([...expandedRowKeys, key]);
        }
    };

    // 修改
    const updateTableInfo = async (params: T) => {
        if (modalFormMode.mode === 'add') {
            // 新增请求
            await props.addTableItem(params);

            // 刷新
            actionRef?.current?.reload();
            return true;
        }
        // 更新编辑请求
        const res = await props.updateTableItem(params);

        if (res) {
            // 刷新
            actionRef?.current?.reload();
            message.success('提交成功');
            return true;
        }
        return false;
    };

    const addFn = () => {
        setModalFormMode({ title: '新增', mode: 'add' });
        setDrawerVisit(true);
        setDrawerFormValues(null as any);
    };
    const catDetailFn = (row: T) => {
        setModalFormMode({ title: '查看', mode: 'cat' });
        setDrawerVisit(true);
        setDrawerFormValues({ ...row });
    };
    const editModeFormFn = (row: T) => {
        setModalFormMode({ title: '编辑', mode: 'edit' });
        setDrawerVisit(true);
        setDrawerFormValues({ ...row });
    };

    const handleRemove = async (selectedRows: { id: any }) => {
        const hide = message.loading('删除中');
        if (!selectedRows) return true;
        try {
            hide();
            //发送删除请求
            await props.deleteTableItem(selectedRows.id);
            // 刷新
            actionRef?.current?.reload();
            return true;
        } catch (error) {
            hide();
            message.error('删除失败，请重试');
            return false;
        }
    };

    const columns: ProColumns<T>[] = [
        {
            title: '操作',
            valueType: 'option',
            key: 'option',
            render: (_text: any, record: any) => [
                <a rel="noopener noreferrer" key="view" onClick={() => catDetailFn(record)}>
                    查看
                </a>,
                <a key="edit" onClick={() => editModeFormFn(record)}>
                    编辑
                </a>,
                <Popconfirm
                    key="del"
                    title="是否确认删除?"
                    onConfirm={() => handleRemove(record)}
                    // onCancel={() => { }}
                    okText="确认"
                    cancelText="取消"
                >
                    <a style={{ color: 'red' }} href="#">
                        删除
                    </a>
                </Popconfirm>,
            ],
        },
    ];

    const DrawEditorComponnentsAdapter = (col: ProColumns<T> & { attr?: RecordAttr<T> }) => {
        const InputComponent = (
            <ProFormText
                width="md"
                name={col.dataIndex}
                initialValue={(drawerFormValues && drawerFormValues[col.dataIndex as never]) || null}
                disabled={modalFormMode.mode === 'cat'}
                label={col.title as string}
                placeholder={`请输入${col.title}`}
                {...props}
            />
        );

        if (!col.attr) return InputComponent;

        if (col.attr.customComponent) {
            return col.attr.customComponent(drawerFormValues || {});
        }

        switch (col.attr.type) {
            case 'input':
                return InputComponent;
            case 'select':
                return (
                    <ProFormSelect
                        width="md"
                        options={col.attr.option}
                        name="roles"
                        initialValue={drawerFormValues[col.dataIndex as never] || null}
                        disabled={modalFormMode.mode === 'cat'}
                        label={col.title as string}
                    />
                );
            default:
                return <></>;
        }
    };

    return (
        <>
            <ProTable<T>
                rowKey="id"
                columns={
                    [
                        ...props.columns.map(v => ({
                            ...v,
                            hideInSearch: v.hideInSearch == undefined ? true : v.hideInSearch,
                        })),
                        ...columns,
                    ] as any
                }
                actionRef={actionRef}
                cardBordered
                bordered
                expandable={{
                    expandedRowKeys,
                    onExpand: handleExpand,
                }}
                request={async (params, sort, filter) => {
                    return await props.getTableData(params, sort, filter);
                }}
                scroll={{ y: 640 }}
                columnsState={{
                    persistenceKey: 'pro-table-singe-menu-manage',
                    persistenceType: 'localStorage',
                }}
                search={{
                    labelWidth: 'auto',
                }}
                options={{
                    setting: {
                        listsHeight: 400,
                    },
                }}
                pagination={{
                    pageSize: 10,
                }}
                dateFormatter="string"
                headerTitle="菜单列表"
                toolBarRender={() => {
                    return (
                        props.toolBarRender || [
                            <Button key="button" icon={<PlusOutlined />} type="primary" onClick={addFn}>
                                新建
                            </Button>,
                        ]
                    );
                }}
            />
            <DrawerForm
                width={750}
                onOpenChange={setDrawerVisit}
                title={modalFormMode.title}
                open={drawerVisit}
                formRef={drawerFormRef}
                submitter={{
                    render: (props, defaultDoms) => {
                        return [
                            ...defaultDoms,
                            modalFormMode.mode === 'cat' ? (
                                <></>
                            ) : (
                                <Button
                                    key="extra-reset"
                                    onClick={() => {
                                        props.reset();
                                    }}
                                >
                                    {' '}
                                    重置
                                </Button>
                            ),
                        ];
                    },
                }}
                onFinish={async values => {
                    if (modalFormMode.mode === 'edit' || modalFormMode.mode === 'add') {
                        return updateTableInfo(values);
                    }
                    setDrawerVisit(false);
                }}
            >
                <Row gutter={[16, 16]}>
                    {props.columns.map(item => {
                        return (
                            <>
                                <Col key={item.index} span={12}>
                                    {DrawEditorComponnentsAdapter(item)}
                                </Col>
                            </>
                        );
                    })}
                </Row>
            </DrawerForm>
        </>
    );
}

export default LpProTable;
